/*
* Copyright (C) 2008-2009 
* J-P Nurmi jpnurmi@gmail.com
* V Jousse vjousse@gmail.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* $Id: application.cpp 293 2009-02-15 09:52:20Z vjousse $
*/

#ifndef CONTROLLER_H
#define CONTROLLER_H

#include <QHash>
#include <QObject>
#include <QVariant>
#include "server.h"

class Viewer;
class MessageView;
class QTreeView;
class QModelIndex;

namespace Irc { class Session; }

class IrcModel;
class ViewModel;
class MessageParser;

/*!
Controller class, implementing Singleton pattern

Link between the view and the model (Irc::Session)
*/

class Controller : public QObject
{
    Q_OBJECT

private:
    void openView(const QString& receiver, Irc::Session* session);	
    QString prepareTarget(const QString& sender, const QString& receiver, Irc::Session* session, bool create = true, bool inform = true);

	/*!
	Generate a unique Id with the session informations and the target
	This id could be used to identify each messageView clearly
	*/
	uint getTargetId(const QString& target, Irc::Session* session);
	
    struct ControllerData
    {
        IrcModel* model;
        ViewModel* viewModel;
        QHash<uint, MessageView*> messageViews;
    } d;

public:
    Controller(QObject* parent = 0);

	void connectTo(const Server& server);

protected slots:
    void on_connected();
    void on_disconnected();

	
    void on_msgJoined(const QString& origin, const QString& channel);
    void on_msgParted(const QString& origin, const QString& channel, const QString& message);
    void on_msgQuit(const QString& origin, const QString& message);
    void on_msgNickChanged(const QString& origin, const QString& nick);


    void on_msgModeChanged(const QString& origin, const QString& receiver, const QString& mode, const QString& args);
    void on_msgTopicChanged(const QString& origin, const QString& channel, const QString& topic);
    void on_msgInvited(const QString& origin, const QString& receiver, const QString& channel);
    void on_msgKicked(const QString& origin, const QString& channel, const QString& nick, const QString& message);
    void on_msgMessageReceived(const QString& origin, const QString& receiver, const QString& message);
    void on_msgNoticeReceived(const QString& origin, const QString& receiver, const QString& message);

    void on_msgCtcpRequestReceived(const QString& origin, const QString& request);
    void on_msgCtcpReplyReceived(const QString& origin, const QString& reply);
    void on_msgCtcpActionReceived(const QString& origin, const QString& receiver, const QString& action);
    void on_msgNumericMessageReceived(const QString& origin, uint code, const QStringList& params);
    void on_msgUnknownMessageReceived(const QString& origin, const QStringList& params);

	/*!
	Called by the messageParser when receiving a /query
	*/
	void openView(const QString& receiver);

	/*!
	Called when the current item of the treeView is changed
	*/
	void currentItemChanged(const QModelIndex& index);
    void currentViewChanged(MessageView* view);

private slots:
	void onConnectRequested(const Server& server);
	void send(const QString& msg);
	void logMessage(const QString& receiver, const QString& message);

	
	//void connectToImpl(const QString& host, quint16 port, const QString& password, const QString& nick);

	/*
    Controller(Viewer* viewer, ViewTree* viewTree, QObject* parent = 0);

    Connection* connection() const;
    void setConnection(Connection* connection, bool connectToServer = true);

signals:
    void highlightRequested();

private slots:
    void onConnectedToServer();
    void onDisconnectedFromServer();
    void onConnectionError(QAbstractSocket::SocketError error);

    void onErrorReceived(Irc::Message errorReply, const QVariantList& params);
    void onMessageReceived(Irc::Message message, const QVariantList& params);

    void onCurrentViewChanged(MessageView* view);
    void onCurrentItemChanged(ViewTreeItem* item);
    void onViewClosed(MessageView* view);

private:
    void setEnabled(bool enabled);
    int receiverId(const QString& receiver) const;
    MessageView* messageView(const QString& receiver, bool server = false) const;
    ViewTreeItem* treeItem(const QString& receiver, bool server = false) const;

    struct ControllerData
    {
        Connection* connection;
        mutable QHash<QString, int> receiverIds;

        Viewer* viewer;
        mutable QHash<int, MessageView*> messageViews;

        ViewTree* viewTree;
        mutable QHash<int, ViewTreeItem*> treeItems;

        static int receiverId;
    } d;
*/
};

#endif // CONTROLLER_H
